/*
@title: fruit_pusher
@description: Push the fruits onto the goals in every level to win!
@author: kirby-b
@tags: ['puzzle']
@addedOn: 2024-01-15

*/

const player = "p"
const apple = "a"
const banana = "b"
const orange = "o"
const goal = "g";
const wall = "w";
const trophy = "t";

setLegend(
  [ player, bitmap`
.......000......
.......000......
......00000.....
.......L1L......
......L11L......
......L111L.....
...L..L818L..L..
...LLLL111LLLL..
......L555L.....
......L111L.....
.....L1111L.....
.....L111L......
......LLL.......
......L.L.......
.....LL.LL......
................` ],
  [ apple, bitmap`
................
..........C.....
.........C......
.........C......
........C.......
......333333....
.....33333333...
.....33333333...
.....33333333...
.....33333333...
.....33333333...
.....33333333...
......333333....
................
................
................` ],
  [ banana, bitmap`
................
................
................
..C.............
..66............
..666...........
..6666..........
...6666.........
...666666.......
....666666......
.....666666.....
......666666....
.......666666...
.........6666C..
................
................` ],
  [ orange, bitmap`
................
................
................
................
................
......99CC9.....
.....9999999....
....999999999...
....999999999...
....999999999...
....999999999...
....999999999...
.....9999999....
......99999.....
................
................` ],
  [ trophy, bitmap`
................
................
.....6666266....
.....6666626....
....626006626...
...6.6260666.6..
...6.6620666.6..
...6.6660666.6..
....666000666...
.....6666626....
......66666.....
.......666......
.......666......
.......666......
.......666......
.....6666666....`],
  [ goal, bitmap`
................
..4.4.4..4..444.
..4.4.4..4..4.4.
..44444..4..4.4.
................
................
.4.4.4..4..444..
.4.4.4..4..4.4..
.44444..4..4.4..
................
................
..4.4.4..4..444.
..4.4.4..4..4.4.
..44444..4..4.4.
................
................`],
  [ wall, bitmap`
0000000000000000
0000000000000000
0000000000000000
0000000000000000
0000000000000000
0000000000000000
0000000000000000
0000000000000000
0000000000000000
0000000000000000
0000000000000000
0000000000000000
0000000000000000
0000000000000000
0000000000000000
0000000000000000`]
);

setSolids([])

let level = 0
const levels = [
  map`
p..
.ag
...`,
  map`
p.g
.b.
...`,
  map`
p..g
.o..
....
..bg`,
  map`
p...
.ob.
....
gg..`,
  map`
.p..g
b....
..go.
....a
g....`,
  map`
p..g..
...b.g
...b..
..o...
g.aga.
....g.`,
  map`
pwgwgw
.w.w.w
......
......
.o..b.
......`,
  map`
p....w
.waw.w
.b...w
...w.w
.g...w
wwwwgw`,
  map`
p.wwww
...a.w
..b..g
ww...w
g.o..w
wwwwgw`,
  map`
p.....
..a.b.
..www.
.o....
..wwww
...ggg`, //start new maps here
  map`
ww.....
wp.....
..b.wwg
.b....w
www.a.w
g.....w
wwww..g`,
  map`
wwwwwww
g...b.w
p.....w
.w.ww.w
.wow...
.w.w...
...wwwg`,
  map`
.wwww.g
pwg....
.wwwwao
.wg....
.www...
.b.....
wwwww..`,
  map`
....wwww
.pa.wg..
....ww..
w.......
w.b.....
w....o.w
www..www
wg.....g`,
  map`
g.a...wg
ww..o.w.
.b......
...pa...
w.wwww.a
w.wg....
w.www...
wgwg....`,
  map`
....b...g
wg.....ww
ww..g....
w..www...
w......a.
p.b....o.
w...www..
w...wg...
g..a.....`,
  map`
wpw....gw
w.w...a.w
w.wgw...w
wbwwww..w
w.wwg..aw
w.wwww..w
........w
........w
wwwwww..w`,
  map`
p.........
.t......t.
.bww..ww..
..wga.gw..
....gg....
....gg.o..
..wg..gw..
..wwb.ww..
.t......t.
..........`
]

const currentLevel = levels[level];
setMap(currentLevel);

setSolids([ player, apple, banana, orange, wall, trophy ]); // other sprites cannot go inside of these sprites

setPushables({
  [ player ]: [apple, banana, orange, trophy]
})

onInput("w", () => {
  getFirst(player).y -= 1
})
onInput("s", () => {
  getFirst(player).y += 1
})
onInput("a", () => {
  getFirst(player).x -= 1
})
onInput("d", () => {
  getFirst(player).x += 1
})

onInput("j", () => {
  const currentLevel = levels[level]; // get the original map of the level

  // make sure the level exists before we load it
  if (currentLevel !== undefined) {
    clearText("");
    setMap(currentLevel);
  }
});

afterInput(() => {
  // count the number of tiles with goals
  const targetNumber = tilesWith(goal).length;
  
  // count the number of tiles with goals and boxes
  const numberCovered = tilesWith(goal, apple).length + tilesWith(goal, banana).length + tilesWith(goal, orange).length + tilesWith(goal, trophy).length;

  // if the number of goals is the same as the number of goals covered
  // all goals are covered and we can go to the next level
  if (numberCovered === targetNumber) {
    // increase the current level number
    level = level + 1;

    const currentLevel = levels[level];

    // make sure the level exists and if so set the map
    // otherwise, we have finished the last level, there is no level
    // after the last level
    if (currentLevel !== undefined) {
      setMap(currentLevel);
    } else {
      addText("You are the winner!", { y: 4, color: color`3` });
    }
  }
});
